<?php

namespace app\common\model;

use app\common\model\Category as CategoryModel;
use app\common\model\ModuleField as ModuleFieldModel;
use think\Collection;
use Exception;
use think\facade\Cache;
use think\facade\Log;

class ModuleField extends CommonBase
{
    private const _CACHE_KEY = '%s_module_fields';
    protected $name = 'field';

    public function __construct(array $data = [], string $connection = 'mysql')
    {
        parent::__construct($data);
        $this->connection = $connection;
    }

    public function getAllModuleField(array $where = []): array
    {
        $cacheKey     = sprintf(self::_CACHE_KEY, $this->connection);
        $moduleFields = Cache::get($cacheKey);
        if (empty($moduleFields)) {
            $moduleFields = $this->where(['is_delete' => config('status.mysql.table_normal')])->order('sort asc')->select()->toArray();
            Cache::set($cacheKey, $moduleFields, self::CACHE_EXPIRE_TIME);
        }

        $res = [];
        foreach ($moduleFields as $moduleField) {
            $flag = true;
            foreach ($where as $key => $value) {
                if (is_array($value) && count($value) == 3 && $value[1] == 'in' && is_array($value[2])) {
                    if (!in_array($moduleField[$value[0]], $value[2])) {
                        $flag = false;
                        break;
                    }
                } else if ($moduleField[$key] != $value) {
                    $flag = false;
                    break;
                }
            }

            if ($flag) {
                $res[$moduleField['id']] = $moduleField;
            }
        }

        return $res;
    }

    public function getModuleFieldList(int $page = 1, int $limit = 10, array $where = []): Collection
    {
        $where['is_delete'] = config('status.mysql.table_normal');
        $offset             = ($page - 1) * $limit;
        return $this->where($where)->order('sort asc')->limit($offset, $limit)->select();
    }

    public function getModuleFieldCount(array $where = []): int
    {
        $where['is_delete'] = config('status.mysql.table_normal');
        return $this->where($where)->count();
    }

    public function findModuleFieldById(int $id)
    {
        return $this->where(['id' => $id, 'is_delete' => config('status.mysql.table_normal')])->find();
    }

    public function findModuleFieldByModuleId(int $moduleId): Collection
    {
        return $this->where(['module_id' => $moduleId, 'is_delete' => config('status.mysql.table_normal')])->select();
    }

    public function findModuleFieldByCode(int $moduleId, string $code)
    {
        return $this->where(['module_id' => $moduleId, 'code' => $code, 'is_delete' => config('status.mysql.table_normal')])->find();
    }

    public function addModuleField(array $data): bool
    {
        $data['is_delete']  = config('status.mysql.table_normal');
        $data['created_at'] = date('Y-m-d H:i:s');
        $data['updated_at'] = date('Y-m-d H:i:s');

        $row = $this->where([
            'is_delete' => config('status.mysql.table_delete'),
            'module_id' => $data['module_id'],
            'code'      => $data['code']])->find();
        if (!empty($row)) {
            $existModuleField = $row->toArray();
            return (boolean)$this->where(['id' => $existModuleField['id']])->save(array_merge($existModuleField, $data));
        }

        $res = (boolean)$this->insert($data);
        Cache::delete(sprintf(self::_CACHE_KEY, $this->connection));
        return $res;
    }

    public function updateModuleField(int $id, array $data): bool
    {
        $data['updated_at'] = date('Y-m-d H:i:s');
        $res                = (boolean)$this->where(['id' => $id])->save($data);
        Cache::delete(sprintf(self::_CACHE_KEY, $this->connection));
        return $res;
    }

    /**
     * @throws Exception
     */
    public function batchModuleFieldSort(array $data): bool
    {
        try {
            $this->startTrans();
            foreach ($data as $id => $sort) {
                $this->where('id', $id)->update(['sort' => $sort]);
            }

            $this->commit();
            Cache::delete(sprintf(self::_CACHE_KEY, $this->connection));
            return true;
        } catch (Exception $e) {
            $this->rollback();
            throw new Exception($e->getMessage());
        }
    }

    public function deleteModuleField(int $id): bool
    {
        $row = $this->findModuleFieldById($id);
        if (empty($row)) {
            return true;
        }
        $res = (boolean)$this->where(['id' => $id])->save(['is_delete' => config('status.mysql.table_delete')]);
        Cache::delete(sprintf(self::_CACHE_KEY, $this->connection));
        return $res;
    }

    public function getArticleFields(int $categoryId): array
    {
        $categoryModel = new CategoryModel([], $this->connection);
        $categories    = $categoryModel->getAllCategory();
        $category      = $categories[$categoryId];
        $moduleId      = $category['module_id'];

        $moduleFieldModel = new ModuleFieldModel([], $this->connection);

        $rows         = $moduleFieldModel->getAllModuleField(['module_id' => $moduleId, 'status' => self::IS_ENABLE_STATUS]);
        $moduleFields = [];
        foreach ($rows as $row) {
            $moduleFields[$row['code']] = $row;
        }
        return $moduleFields;
    }

    public function clearModuleFieldCache(): bool
    {
        return Cache::delete(sprintf(self::_CACHE_KEY, $this->connection));
    }

}
